package cn.tqfeiyang.springplus.generator.name;

import cn.tqfeiyang.springplus.generator.config.GeneratorConfig;
import cn.tqfeiyang.springplus.generator.jdbc.FieldInfo;
import cn.tqfeiyang.springplus.generator.jdbc.TableInfo;
import cn.tqfeiyang.springplus.generator.util.Pluralizer;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.io.File;
import java.util.*;

/**
 * 名称转换器
 */
public class NameConverter {

    private final GeneratorConfig generatorConfig;

    public NameConverter(GeneratorConfig generatorConfig) {
        this.generatorConfig = generatorConfig;
    }

    /**
     * 名称转换
     *
     * @param tableInfo
     * @param nameFormat
     * @return
     */
    public String convert(TableInfo tableInfo, NameFormat nameFormat) {
        switch (nameFormat) {
            case ModuleName:
                return String.format("%s", moduleName(tableInfo));
            case EntityName:
                return String.format("%s", entityName(tableInfo));
            case ConstantName:
                return String.format("%s", camelTounderline(convert(tableInfo, NameFormat.EntityName)).toUpperCase());
            case CacheNamespace:
                return String.format("%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"));
            case CachePrefix:
                return String.format("%s", camelTounderline(convert(tableInfo, NameFormat.EntityName)).toLowerCase());
            case VariableName:
            case PropertyName:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.EntityName)));
            case PluralVariableName:
            case PluralPropertyName:
                return String.format("%s", Pluralizer.toPlural(convert(tableInfo, NameFormat.VariableName)));
            case ListVariableName:
            case ListPropertyName:
                return String.format("%sList", convert(tableInfo, NameFormat.VariableName));
            case InfoVariableName:
            case InfoPropertyName:
                return String.format("%sInfo", convert(tableInfo, NameFormat.VariableName));
            case EntityClass:
                return String.format("%sEntity", convert(tableInfo, NameFormat.EntityName));
            case EntityPackage:
                return String.format("%s.entity", packageName(tableInfo));
            case EntityImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.EntityPackage), convert(tableInfo, NameFormat.EntityClass));
            case EntityJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.EntityImport))).replace('/', File.separatorChar);
            case EntityVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.EntityClass)));
            case EntityListMethod:
                //return String.format("query%s", Pluralizer.toPlural(convert(tableInfo, NameFormat.EntityName)));
                return String.format("get%sList", convert(tableInfo, NameFormat.EntityName));
            case EntityListAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityListMapping));
            case EntityListMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityListMethod));
            case EntityTreeMethod:
                return String.format("get%sTree", convert(tableInfo, NameFormat.EntityName));
            case EntityTreeAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityTreeMapping));
            case EntityTreeMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityTreeMethod));
            case EntityPageMethod:
                //return String.format("get%sPage", convert(tableInfo, NameFormat.EntityName));
                return String.format("query%s", Pluralizer.toPlural(convert(tableInfo, NameFormat.EntityName)));
            case EntityPageAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityPageMapping));
            case EntityPageMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityPageMethod));
            case EntityInfoMethod:
                return String.format("get%sInfo", convert(tableInfo, NameFormat.EntityName));
            case EntityInfoAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityInfoMapping));
            case EntityInfoMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityInfoMethod));
            case EntityMapMethod:
                return String.format("get%sMap", convert(tableInfo, NameFormat.EntityName));
            case EntityMapAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityMapMapping));
            case EntityMapMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityMapMethod));
            case EntityDetailMethod:
                //return String.format("get%sDetail", convert(tableInfo, NameFormat.EntityName));
                return String.format("read%s", convert(tableInfo, NameFormat.EntityName));
            case EntityDetailAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityDetailMapping));
            case EntityDetailMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityDetailMethod));
            case EntityCreateMethod:
                return String.format("create%s", convert(tableInfo, NameFormat.EntityName));
            case EntityCreateAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityCreateMapping));
            case EntityCreateMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityCreateMethod));
            case EntityUpdateMethod:
                return String.format("update%s", convert(tableInfo, NameFormat.EntityName));
            case EntityUpdateAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityUpdateMapping));
            case EntityUpdateMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityUpdateMethod));
            case EntityDeleteMethod:
                return String.format("delete%s", convert(tableInfo, NameFormat.EntityName));
            case EntityDeleteAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityDeleteMapping));
            case EntityDeleteMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityDeleteMethod));
            case EntityBatchDeleteMethod:
                return String.format("batchDelete%s", Pluralizer.toPlural(convert(tableInfo, NameFormat.EntityName)));
            case EntityBatchDeleteAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityBatchDeleteMapping));
            case EntityBatchDeleteMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityBatchDeleteMethod));
            case EntityCheckMethod:
                return String.format("check%sExists", convert(tableInfo, NameFormat.EntityName));
            case EntityCheckAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityCheckMapping));
            case EntityCheckMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityCheckMethod));
            case EntityExportExcelMethod:
                return String.format("export%sToExcel", Pluralizer.toPlural(convert(tableInfo, NameFormat.EntityName)));
            case EntityExportExcelAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityExportExcelMapping));
            case EntityExportExcelMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityExportExcelMethod));
            case EntityImportExcelMethod:
                return String.format("import%sFromExcel", Pluralizer.toPlural(convert(tableInfo, NameFormat.EntityName)));
            case EntityImportExcelAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityImportExcelMapping));
            case EntityImportExcelMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityImportExcelMethod));
            case EntityDownloadTemplateMethod:
                return String.format("download%sTemplate", convert(tableInfo, NameFormat.EntityName));
            case EntityDownloadTemplateAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityDownloadTemplateMapping));
            case EntityDownloadTemplateMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityDownloadTemplateMethod));
            case EntityClearCacheMethod:
                return String.format("clear%sCache", convert(tableInfo, NameFormat.EntityName));
            case EntityClearCacheAuthorize:
                return String.format("%s:%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)), convert(tableInfo, NameFormat.EntityClearCacheMapping));
            case EntityClearCacheMapping:
                return String.format("%s", convert(tableInfo, NameFormat.EntityClearCacheMethod));
            case EntityAuthorizePrefix:
                return String.format("%s:%s", convert(tableInfo, NameFormat.ModuleName).replace(".", ":"), camelName(convert(tableInfo, NameFormat.EntityName)));
            case MapperClass:
                return String.format("%sMapper", convert(tableInfo, NameFormat.EntityName));
            case MapperPackage:
                return String.format("%s.mapper", packageName(tableInfo));
            case MapperImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.MapperPackage), convert(tableInfo, NameFormat.MapperClass));
            case MapperJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.MapperImport))).replace('/', File.separatorChar);
            case MapperXmlFile:
                return String.format("src/main/resources/mapper/%s/%s.xml", convert(tableInfo, NameFormat.ModuleName).replace(".", "/"), convert(tableInfo, NameFormat.MapperClass)).replace('/', File.separatorChar);
                //return String.format("src/main/java/%s.xml", classToFile(convert(tableInfo, NameFormat.MapperImport))).replace('/', File.separatorChar);
            case MapperVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.MapperClass)));
            case MapperListMethod:
                return String.format("get%sList", convert(tableInfo, NameFormat.ResponseQueryClass));
            case ServiceClass:
                return String.format("%sCurdService", convert(tableInfo, NameFormat.EntityName));
            case ServicePackage:
                return String.format("%s.service", packageName(tableInfo));
            case ServiceImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ServicePackage), convert(tableInfo, NameFormat.ServiceClass));
            case ServiceJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ServiceImport))).replace('/', File.separatorChar);
            case ServiceVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ServiceClass)));
            case ServiceImplClass:
                return String.format("%sCurdServiceImpl", convert(tableInfo, NameFormat.EntityName));
            case ServiceImplPackage:
                return String.format("%s.service.impl", packageName(tableInfo));
            case ServiceImplImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ServiceImplPackage), convert(tableInfo, NameFormat.ServiceImplClass));
            case ServiceImplJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ServiceImplImport))).replace('/', File.separatorChar);
            case ServiceImplVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ServiceImplClass)));
            case CurdServiceClass:
                return String.format("%sCurdService", convert(tableInfo, NameFormat.EntityName));
            case CurdServicePackage:
                return String.format("%s.service", packageName(tableInfo));
            case CurdServiceImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.CurdServicePackage), convert(tableInfo, NameFormat.CurdServiceClass));
            case CurdServiceJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.CurdServiceImport))).replace('/', File.separatorChar);
            case CurdServiceVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.CurdServiceClass)));
            case ExcelServiceClass:
                return String.format("%sExcelService", convert(tableInfo, NameFormat.EntityName));
            case ExcelServicePackage:
                return String.format("%s.service", packageName(tableInfo));
            case ExcelServiceImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ExcelServicePackage), convert(tableInfo, NameFormat.ExcelServiceClass));
            case ExcelServiceJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ExcelServiceImport))).replace('/', File.separatorChar);
            case ExcelServiceVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ExcelServiceClass)));
            case AssignServiceClass:
                return String.format("%sAssignService", convert(tableInfo, NameFormat.EntityName));
            case AssignServicePackage:
                return String.format("%s.service", packageName(tableInfo));
            case AssignServiceImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.AssignServicePackage), convert(tableInfo, NameFormat.AssignServiceClass));
            case AssignServiceJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.AssignServiceImport))).replace('/', File.separatorChar);
            case AssignServiceVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.AssignServiceClass)));
            case CacheServiceClass:
                return String.format("%sCacheService", convert(tableInfo, NameFormat.EntityName));
            case CacheServicePackage:
                return String.format("%s.service", packageName(tableInfo));
            case CacheServiceImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.CacheServicePackage), convert(tableInfo, NameFormat.CacheServiceClass));
            case CacheServiceJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.CacheServiceImport))).replace('/', File.separatorChar);
            case CacheServiceVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.CacheServiceClass)));
            case ListServiceClass:
                return String.format("%sListService", convert(tableInfo, NameFormat.EntityName));
            case ListServicePackage:
                return String.format("%s.service", packageName(tableInfo));
            case ListServiceImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ListServicePackage), convert(tableInfo, NameFormat.ListServiceClass));
            case ListServiceJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ListServiceImport))).replace('/', File.separatorChar);
            case ListServiceVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ListServiceClass)));
            case TreeServiceClass:
                return String.format("%sTreeService", convert(tableInfo, NameFormat.EntityName));
            case TreeServicePackage:
                return String.format("%s.service", packageName(tableInfo));
            case TreeServiceImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.TreeServicePackage), convert(tableInfo, NameFormat.TreeServiceClass));
            case TreeServiceJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.TreeServiceImport))).replace('/', File.separatorChar);
            case TreeServiceVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.TreeServiceClass)));
            case RequestClass:
                return String.format("%sDTO", convert(tableInfo, NameFormat.EntityName));
            case RequestPackage:
                return String.format("%s.request", packageName(tableInfo));
            case RequestImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.RequestPackage), convert(tableInfo, NameFormat.RequestClass));
            case RequestJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.RequestImport))).replace('/', File.separatorChar);
            case RequestVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.RequestClass)));
            case RequestQueryClass:
                return String.format("%sQueryDTO", convert(tableInfo, NameFormat.EntityName));
            case RequestQueryPackage:
                return String.format("%s.request", packageName(tableInfo));
            case RequestQueryImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.RequestPackage), convert(tableInfo, NameFormat.RequestQueryClass));
            case RequestQueryJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.RequestQueryImport))).replace('/', File.separatorChar);
            case RequestQueryVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.RequestQueryClass)));
            case RequestCreateClass:
                return String.format("%sCreateDTO", convert(tableInfo, NameFormat.EntityName));
            case RequestCreatePackage:
                return String.format("%s.request", packageName(tableInfo));
            case RequestCreateImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.RequestPackage), convert(tableInfo, NameFormat.RequestCreateClass));
            case RequestCreateJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.RequestCreateImport))).replace('/', File.separatorChar);
            case RequestCreateVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.RequestCreateClass)));
            case RequestUpdateClass:
                return String.format("%sUpdateDTO", convert(tableInfo, NameFormat.EntityName));
            case RequestUpdatePackage:
                return String.format("%s.request", packageName(tableInfo));
            case RequestUpdateImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.RequestPackage), convert(tableInfo, NameFormat.RequestUpdateClass));
            case RequestUpdateJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.RequestUpdateImport))).replace('/', File.separatorChar);
            case RequestUpdateVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.RequestUpdateClass)));
            case ResponseClass:
                return String.format("%sVO", convert(tableInfo, NameFormat.EntityName));
            case ResponsePackage:
                return String.format("%s.response", packageName(tableInfo));
            case ResponseImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ResponsePackage), convert(tableInfo, NameFormat.ResponseClass));
            case ResponseJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ResponseImport))).replace('/', File.separatorChar);
            case ResponseVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ResponseClass)));
            case ResponseQueryClass:
                return String.format("%sQueryVO", convert(tableInfo, NameFormat.EntityName));
            case ResponseQueryPackage:
                return String.format("%s.response", packageName(tableInfo));
            case ResponseQueryImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ResponseQueryPackage), convert(tableInfo, NameFormat.ResponseQueryClass));
            case ResponseQueryJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ResponseQueryImport))).replace('/', File.separatorChar);
            case ResponseQueryVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ResponseQueryClass)));
            case ResponseDetailClass:
                return String.format("%sDetailVO", convert(tableInfo, NameFormat.EntityName));
            case ResponseDetailPackage:
                return String.format("%s.response", packageName(tableInfo));
            case ResponseDetailImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ResponseDetailPackage), convert(tableInfo, NameFormat.ResponseDetailClass));
            case ResponseDetailJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ResponseDetailImport))).replace('/', File.separatorChar);
            case ResponseDetailVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ResponseDetailClass)));
            case ResponseTreeClass:
                return String.format("%sTreeVO", convert(tableInfo, NameFormat.EntityName));
            case ResponseTreePackage:
                return String.format("%s.response", packageName(tableInfo));
            case ResponseTreeImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ResponseTreePackage), convert(tableInfo, NameFormat.ResponseTreeClass));
            case ResponseTreeJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ResponseTreeImport))).replace('/', File.separatorChar);
            case ResponseTreeVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ResponseTreeClass)));
            case FilterableClass:
                return String.format("%sSTO", convert(tableInfo, NameFormat.EntityName));
            case FilterablePackage:
                return String.format("%s.request", packageName(tableInfo));
            case FilterableImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.FilterablePackage), convert(tableInfo, NameFormat.FilterableClass));
            case FilterableJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.FilterableImport))).replace('/', File.separatorChar);
            case FilterableVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.FilterableClass)));
            case ControllerClass:
                return String.format("%sCurdController", convert(tableInfo, NameFormat.EntityName));
            case ControllerPackage:
                return String.format("%s.controller", packageName(tableInfo));
            case ControllerImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ControllerPackage), convert(tableInfo, NameFormat.ControllerClass));
            case ControllerJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ControllerImport))).replace('/', File.separatorChar);
            case ControllerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ControllerClass)));
            case CurdControllerClass:
                return String.format("%sCurdController", convert(tableInfo, NameFormat.EntityName));
            case CurdControllerPackage:
                return String.format("%s.controller", packageName(tableInfo));
            case CurdControllerImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.CurdControllerPackage), convert(tableInfo, NameFormat.CurdControllerClass));
            case CurdControllerJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.CurdControllerImport))).replace('/', File.separatorChar);
            case CurdControllerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.CurdControllerClass)));
            case ExcelControllerClass:
                return String.format("%sExcelController", convert(tableInfo, NameFormat.EntityName));
            case ExcelControllerPackage:
                return String.format("%s.controller", packageName(tableInfo));
            case ExcelControllerImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ExcelControllerPackage), convert(tableInfo, NameFormat.ExcelControllerClass));
            case ExcelControllerJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ExcelControllerImport))).replace('/', File.separatorChar);
            case ExcelControllerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ExcelControllerClass)));
            case AssignControllerClass:
                return String.format("%sAssignController", convert(tableInfo, NameFormat.EntityName));
            case AssignControllerPackage:
                return String.format("%s.controller", packageName(tableInfo));
            case AssignControllerImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.AssignControllerPackage), convert(tableInfo, NameFormat.AssignControllerClass));
            case AssignControllerJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.AssignControllerImport))).replace('/', File.separatorChar);
            case AssignControllerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.AssignControllerClass)));
            case CacheControllerClass:
                return String.format("%sCacheController", convert(tableInfo, NameFormat.EntityName));
            case CacheControllerPackage:
                return String.format("%s.controller", packageName(tableInfo));
            case CacheControllerImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.CacheControllerPackage), convert(tableInfo, NameFormat.CacheControllerClass));
            case CacheControllerJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.CacheControllerImport))).replace('/', File.separatorChar);
            case CacheControllerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.CacheControllerClass)));
            case TreeControllerClass:
                return String.format("%sTreeController", convert(tableInfo, NameFormat.EntityName));
            case TreeControllerPackage:
                return String.format("%s.controller", packageName(tableInfo));
            case TreeControllerImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.TreeControllerPackage), convert(tableInfo, NameFormat.TreeControllerClass));
            case TreeControllerJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.TreeControllerImport))).replace('/', File.separatorChar);
            case TreeControllerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.TreeControllerClass)));
            case ConstantClass:
                return String.format("%sConstants", convert(tableInfo, NameFormat.EntityName));
            case ConstantPackage:
                return String.format("%s.constant", packageName(tableInfo));
            case ConstantImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ConstantPackage), convert(tableInfo, NameFormat.ConstantClass));
            case ConstantJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ConstantImport))).replace('/', File.separatorChar);
            case ControllerTestsClass:
                return String.format("%sControllerTests", convert(tableInfo, NameFormat.EntityName));
            case ControllerTestsJavaFile:
                return String.format("src/test/java/%sTests.java", classToFile(convert(tableInfo, NameFormat.ControllerImport))).replace('/', File.separatorChar);
            case ListenerClass:
                return String.format("%sListener", convert(tableInfo, NameFormat.EntityName));
            case ListenerPackage:
                return String.format("%s.listener", packageName(tableInfo));
            case ListenerImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ListenerPackage), convert(tableInfo, NameFormat.ListenerClass));
            case ListenerJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ListenerImport))).replace('/', File.separatorChar);
            case ListenerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ListenerClass)));
            case ValidatorClass:
                return String.format("%sValidator", convert(tableInfo, NameFormat.EntityName));
            case ValidatorPackage:
                return String.format("%s.validator", packageName(tableInfo));
            case ValidatorImport:
                return String.format("%s.%s", convert(tableInfo, NameFormat.ValidatorPackage), convert(tableInfo, NameFormat.ValidatorClass));
            case ValidatorJavaFile:
                return String.format("src/main/java/%s.java", classToFile(convert(tableInfo, NameFormat.ValidatorImport))).replace('/', File.separatorChar);
            case ValidatorVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.ValidatorClass)));
            case RequestUrl:
                //return String.format("/api/%s/%s/v1", convert(tableInfo, NameFormat.ModuleName), Pluralizer.toPlural(camelName(convert(tableInfo, NameFormat.EntityName))));
                return String.format("/api/%s/%s", convert(tableInfo, NameFormat.ModuleName).replace(".", "/"), camelName(convert(tableInfo, NameFormat.EntityName)));
            case ApifoxFolder:
                return String.format("%s", apifoxFolder(tableInfo));
            case MysqlSQLFile:
                return String.format("mysql/%s.sql", tableInfo.getName());
            case CountOfMethod:
                return String.format("countOf%s", Pluralizer.toPlural(convert(tableInfo, NameFormat.EntityName)));
            case VueApiClass:
                return String.format("%sApi", convert(tableInfo, NameFormat.EntityName));
            case VueApiVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.VueApiClass)));
            case VueApiName:
                return String.format("%s", NamingStrategy.camelToUnderline(convert(tableInfo, NameFormat.VueApiVariable)).replace("_", "-"));
            case VueApiImport:
                return String.format("api/%s/%s",
                        convert(tableInfo, NameFormat.ModuleName).replace(".", "/"),
                        convert(tableInfo, NameFormat.VueApiName));
            case VueApiFile:
                return String.format("vue/%s.js", convert(tableInfo, NameFormat.VueApiImport));
            case VueListClass:
                return String.format("%sList", convert(tableInfo, NameFormat.EntityName));
            case VueListVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.VueListClass)));
            case VueListName:
                return String.format("%s", NamingStrategy.camelToUnderline(convert(tableInfo, NameFormat.VueListVariable)).replace("_", "-"));
            case VueListImport:
                return String.format("views/%s/%s/%s",
                        convert(tableInfo, NameFormat.ModuleName).replace(".", "/"),
                        NamingStrategy.camelToUnderline(convert(tableInfo, NameFormat.EntityName)).replace("_", "-"),
                        convert(tableInfo, NameFormat.VueListName));
            case VueListFile:
                return String.format("vue/%s.vue", convert(tableInfo, NameFormat.VueListImport));
            case VueDrawerClass:
                return String.format("%sDrawer", convert(tableInfo, NameFormat.EntityName));
            case VueDrawerVariable:
                return String.format("%s", camelName(convert(tableInfo, NameFormat.VueDrawerClass)));
            case VueDrawerName:
                return String.format("%s", NamingStrategy.camelToUnderline(convert(tableInfo, NameFormat.VueDrawerVariable)).replace("_", "-"));
            case VueDrawerImport:
                return String.format("views/%s/%s/components/%s",
                        convert(tableInfo, NameFormat.ModuleName).replace(".", "/"),
                        NamingStrategy.camelToUnderline(convert(tableInfo, NameFormat.EntityName)).replace("_", "-"),
                        convert(tableInfo, NameFormat.VueDrawerName));
            case VueDrawerFile:
                return String.format("vue/%s.vue", convert(tableInfo, NameFormat.VueDrawerImport));
            default:
                throw new RuntimeException(String.format("不支持的名称格式 %s", nameFormat));
        }
    }

    /**
     * 名称转换
     *
     * @param fieldInfo
     * @param nameFormat
     * @return
     */
    public String convert(FieldInfo fieldInfo, NameFormat nameFormat) {
        switch (nameFormat) {
            case VariableName:
            case PropertyName:
                String variableName = underlineToCamel(fieldInfo.getName(),
                        generatorConfig.getFieldPrefix(), generatorConfig.getFieldSuffix());
                if (generatorConfig.isBooleanColumnRemoveIsPrefix()
                        && "boolean".equalsIgnoreCase(fieldInfo.getColumnType().getType()) && variableName.startsWith("is")) {
                    variableName = StringUtils.removePrefixAfterPrefixToLower(variableName, 2);
                }
                return variableName;
            case PluralVariableName:
                return String.format("%s", Pluralizer.toPlural(convert(fieldInfo, NameFormat.VariableName)));
            case PluralPropertyName:
                return String.format("%s", Pluralizer.toPlural(convert(fieldInfo, NameFormat.PropertyName)));
            case ListVariableName:
            case ListPropertyName:
                return String.format("%sList", convert(fieldInfo, NameFormat.VariableName));
            case InfoVariableName:
            case InfoPropertyName:
                return String.format("%sInfo", convert(fieldInfo, NameFormat.VariableName));
            case PascalPropertyName:
                return String.format("%s", pascalName(convert(fieldInfo, NameFormat.VariableName)));
            case PropertyType:
                return fieldInfo.getColumnType().getType();
            case GetterMethod:
                return getterPrefix(fieldInfo) + pascalName(convert(fieldInfo, NameFormat.VariableName));
            case SetterMethod:
                return "set" + pascalName(convert(fieldInfo, NameFormat.VariableName));
            case ExistsMethod:
                return String.format("check%sExists", pascalName(convert(fieldInfo, NameFormat.VariableName)));
            case FindMethod:
                return String.format("find%sBy%s", convert(fieldInfo.getTable(), NameFormat.EntityName), pascalName(convert(fieldInfo, NameFormat.VariableName)));
            case FieldUpdateMethod:
                return String.format("update%sField", pascalName(convert(fieldInfo, NameFormat.VariableName)));
            case FieldUpdateAuthorize:
                return String.format("%s:%s:%s", convert(fieldInfo.getTable(), NameFormat.ModuleName), camelName(convert(fieldInfo.getTable(), NameFormat.EntityName)), convert(fieldInfo, NameFormat.FieldUpdateMapping));
            case FieldUpdateMapping:
                return String.format("%s", convert(fieldInfo, NameFormat.FieldUpdateMethod));
            default:
                throw new RuntimeException(String.format("不支持的名称格式 %s", nameFormat));
        }
    }

    /**
     * 获取模块名
     *
     * @param tableInfo
     * @return 模块名
     */
    public String moduleName(TableInfo tableInfo) {
        if (StringUtils.isNotBlank(tableInfo.getModuleName())) {
            return tableInfo.getModuleName();
        } else {
            if (StringUtils.isNotBlank(generatorConfig.getModuleName())) {
                return generatorConfig.getModuleName();
            } else if (generatorConfig.isFirstWordAsModuleName()) {
                String[] parts = removePrefixAndSuffix(tableInfo.getName(),
                        generatorConfig.getTablePrefix(),
                        generatorConfig.getFieldSuffix()).split("_");
                if (parts.length >= 2) {
                    return parts[0];
                } else {
                    return "";
                }
            } else {
                return "";
            }
        }
    }

    /**
     * 获取实体名
     *
     * @param tableInfo
     * @return 实体名
     */
    public String entityName(TableInfo tableInfo) {
        if (StringUtils.isNotBlank(tableInfo.getEntityName())) {
            return tableInfo.getEntityName();
        } else {
            String tableName = removePrefixAndSuffix(tableInfo.getName(),
                    generatorConfig.getTablePrefix(), generatorConfig.getFieldSuffix());
            if (generatorConfig.isEntityNameRemoveModulePrefix()) {
                String modulePrefix = moduleName(tableInfo) + "_";
                if (tableName.startsWith(modulePrefix)) {
                    tableName = tableName.substring(modulePrefix.length());
                }
            }
            return pascalName(tableName);
        }
    }

    /**
     * 获取Java包名
     *
     * @param tableInfo
     * @return Java包名
     */
    public String packageName(TableInfo tableInfo) {
        String packageName = generatorConfig.getRootPackage();
        if (generatorConfig.isPackageNameWithModule()) {
            String moduleName = moduleName(tableInfo);
            if (StringUtils.isNotBlank(moduleName)) {
                packageName = packageName + "." + moduleName;
            }
        }
        if (generatorConfig.isPackageNameWithTable()) {
            String entityName = entityName(tableInfo);
            if (StringUtils.isNotBlank(entityName)) {
                packageName = packageName + "." + camelName(entityName);
            }
        }
        return packageName;
    }

    /**
     * Apifox 目录
     *
     * @param tableInfo
     * @return 目录
     */
    public String apifoxFolder(TableInfo tableInfo) {
        String folderName = StringUtils.isNotBlank(tableInfo.getApifoxFolder()) ?
                tableInfo.getApifoxFolder() : generatorConfig.getApifoxFolder();
        if (StringUtils.isNotBlank(folderName)) {
            return "%s/%s".formatted(folderName, tableInfo.getComment());
        } else {
            return tableInfo.getComment();
        }
    }

    /**
     * 类名转路径
     *
     * @param className
     * @return
     */
    public String classToFile(String className) {
        return className.replace(".", File.separator);
    }

    /**
     * Getter方法开始，是is或者get
     *
     * @param fieldInfo
     * @return
     */
    public String getterPrefix(FieldInfo fieldInfo) {
        String variableName = convert(fieldInfo, NameFormat.VariableName);
        if ("boolean".equalsIgnoreCase(fieldInfo.getColumnType().getType()) && !variableName.startsWith("is")) {
            return "is";
        } else {
            return "get";
        }
    }

    /**
     * 获取骆驼(Camel)命名
     *
     * 首个单词的首字母小写，之后单词的首字母都大写，也就是驼峰式命名法里面的小驼峰式命名规则，
     * 例如：selectStudentInfo
     *
     * @param input
     * @return
     */
    public String camelName(String input) {
        return underlineToCamel(input, null, null);
    }

    /**
     * 获取帕斯卡(Pascal)命名
     *
     * 帕斯卡命名法是首字母大写，也就是驼峰式命名法里面的大驼峰式命名规则，
     * 例如：SelectStudentInfo
     *
     * @param input
     * @return
     */
    public String pascalName(String input) {
        return NamingStrategy.capitalFirst(camelName(input));
    }

    /**
     * 下划线转驼峰命名
     *
     * @param input
     * @param prefix
     * @param suffix
     * @return 驼峰命名
     */
    public String underlineToCamel(String input, Set<String> prefix, Set<String> suffix) {
        return NamingStrategy.underlineToCamel(removePrefixAndSuffix(input, prefix, suffix));
    }

    /**
     * 驼峰命名转下划线
     *
     * @param input
     * @return 下划线
     */
    public String camelTounderline(String input) {
        return NamingStrategy.camelToUnderline(input);
    }

    /**
     * 去掉前缀和后缀
     *
     * @param input
     * @param prefix
     * @param suffix
     * @return
     */
    public String removePrefixAndSuffix(String input, Set<String> prefix, Set<String> suffix) {
        String name = input;
        if (prefix != null) {
            name = NamingStrategy.removePrefix(name, prefix);
        }
        if (suffix != null) {
            name = NamingStrategy.removeSuffix(name, suffix);
        }
        return name;
    }
}
